package com.autumn.mybatis.metadata;

import java.util.ArrayList;
import java.util.List;

import com.autumn.mybatis.mapper.annotation.ComplexIndex;
import com.autumn.mybatis.mapper.annotation.ComplexIndexs;
import com.autumn.mybatis.mapper.annotation.Index;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.StringUtils;

/**
 * 实体索引
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2018-01-20 23:48:19
 */
public class EntityIndex {
	private final EntityTable table;
	private final String name;
	private final boolean unique;
	private final List<EntityColumn> columns;

	/**
	 * 实例化
	 * 
	 * @param table
	 *            表
	 * @param name
	 *            名称
	 * @param unique
	 *            是否唯一
	 * @param columns
	 *            列集合
	 */
	public EntityIndex(EntityTable table, String name, boolean unique, List<EntityColumn> columns) {
		super();
		this.table = table;
		this.name = name;
		this.unique = unique;
		this.columns = columns;
	}

	/**
	 * 获取表
	 * 
	 * @return
	 */
	public EntityTable getTable() {
		return table;
	}

	/**
	 * 获取索引名称(
	 * 
	 * @return
	 */
	public String getName() {
		return name;
	}

	/**
	 * 获取自动名称
	 * 
	 * @param prefix
	 *            前缀
	 * @param tableName
	 *            表名
	 * @return
	 */
	public String getAutoName(String prefix, String tableName) {
		if (!StringUtils.isNullOrBlank(this.getName())) {
			return this.getName();
		}
		if (StringUtils.isNullOrBlank(prefix)) {
			prefix = "IX";
		}
		if (StringUtils.isNullOrBlank(tableName)) {
			tableName = this.getTable().getName();
		}
		StringBuilder builder = new StringBuilder();
		builder.append(prefix + "_");
		builder.append(tableName + "_");
		for (int i = 0; i < columns.size(); i++) {
			EntityColumn column = columns.get(i);
			if (i > 0) {
				builder.append("_");
			}
			builder.append(column.getColumnName());
		}
		return builder.toString();
	}

	/**
	 * 获取是否唯一
	 * 
	 * @return
	 */
	public boolean isUnique() {
		return unique;
	}

	/**
	 * 获取列集合
	 * 
	 * @return
	 */
	public List<EntityColumn> getColumns() {
		return columns;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(this.getAutoName(null, null));
		builder.append("(");
		for (int i = 0; i < this.getColumns().size(); i++) {
			EntityColumn column = this.getColumns().get(i);
			if (i > 0) {
				builder.append(",");
			}
			builder.append(column.getColumnName());
		}
		builder.append(")");
		return builder.toString();
	}

	/**
	 * 创建索引
	 * 
	 * @param table
	 *            表
	 * @return
	 */
	static List<EntityIndex> createEntityIndexs(EntityTable table) {
		List<EntityIndex> items = new ArrayList<EntityIndex>();
		List<EntityColumn> columns;
		for (EntityColumn column : table.getColumns()) {
			Index index = column.getProperty().getAnnotation(Index.class);
			if (index != null) {
				columns = new ArrayList<>();
				columns.add(column);
				items.add(new EntityIndex(table, index.name(), index.unique(), columns));
			}
		}
		ComplexIndexs cIndexs = table.getEntityClass().getAnnotation(ComplexIndexs.class);
		if (cIndexs != null) {
			for (ComplexIndex index : cIndexs.indexs()) {
				if (index != null) {
					columns = getIndexColumns(table, index);
					items.add(new EntityIndex(table, index.name(), index.unique(), columns));
				}
			}
		}
		return items;
	}

	private static List<EntityColumn> getIndexColumns(EntityTable table, ComplexIndex index) {
		if (index.propertys() == null || index.propertys().length == 0) {
			ExceptionUtils.throwConfigureException("实体对象 " + table.getEntityClass().getName() + " 的复合索引至少需要一个属性以上。");
		}
		List<EntityColumn> columns = new ArrayList<>();
		for (String property : index.propertys()) {
			if (StringUtils.isNullOrBlank(property)) {
				ExceptionUtils.throwConfigureException(
						"实体对象 " + table.getEntityClass().getName() + " 的复合索引包含无效的属性，属性名为 null 或空白值。");
			}
			EntityColumn column = table.getPropertyMap().get(property);
			if (column == null) {
				ExceptionUtils.throwConfigureException(
						"实体对象 " + table.getEntityClass().getName() + " 的复合索引属性 " + property + " 不存在。");
			}
			columns.add(column);
		}
		return columns;
	}

}
